/*
 * Copyright (C) 2017-2019 Dremio Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.dremio.service.jobs;

import java.util.Locale;

import com.dremio.exec.proto.UserBitShared.RpcEndpointInfos;
import com.dremio.exec.proto.UserBitShared.WorkloadClass;
import com.dremio.exec.proto.UserBitShared.WorkloadType;
import com.dremio.service.job.proto.QueryType;

/**
 * Utility class for query type.
 */
// package private
final class QueryTypeUtils {

  private QueryTypeUtils() {
  }

  /**
   * If the query is submitted by services internally, and not by a user action.
   *
   * @param queryType query type
   * @return iff the query is generated by services internally
   */
  static boolean isInternal(final QueryType queryType) {
    switch (queryType) {

    case UI_INTERNAL_PREVIEW:
    case UI_INTERNAL_RUN:
    case UI_EXPORT:
    case ACCELERATOR_CREATE:
    case ACCELERATOR_DROP:
    case PREPARE_INTERNAL:
    case ACCELERATOR_EXPLAIN:
      return true;

    case UI_RUN:
    case UI_PREVIEW:
    case ODBC:
    case JDBC:
    case REST:
    case UI_INITIAL_PREVIEW:
    case UNKNOWN:
    default:
      return false;
    }
  }

  /**
   * If leaf limits should be enabled for this query.
   *
   * @param queryType query type
   * @return iff leaf limits should be enabled
   */
  static boolean requiresLeafLimits(final QueryType queryType) {
    return queryType == QueryType.UI_PREVIEW ||
        queryType == QueryType.UI_INTERNAL_PREVIEW ||
        queryType == QueryType.UI_INITIAL_PREVIEW;
  }

  /**
   * Get workload class for this query.
   *
   * @param queryType query type
   * @return workload class
   */
  static WorkloadClass getWorkloadClassFor(final QueryType queryType) {
    switch (queryType) {

    case ACCELERATOR_CREATE:
    case ACCELERATOR_DROP:
    case ACCELERATOR_EXPLAIN:
      return WorkloadClass.BACKGROUND;

    case PREPARE_INTERNAL:
    case UI_INTERNAL_PREVIEW:
    case UI_INITIAL_PREVIEW:
    case UI_PREVIEW:
      return WorkloadClass.NRT;

    case UNKNOWN:
    case JDBC:
    case ODBC:
    case REST:
    case UI_EXPORT:
    case UI_INTERNAL_RUN:
    case UI_RUN:
    default:
      return WorkloadClass.GENERAL;
    }
  }

  /**
   * If the query is submitted from the UI.
   *
   * @param queryType query type
   * @return If the query is from the UI
   */
  static boolean isQueryFromUI(final QueryType queryType) {
    switch (queryType) {

    case UI_RUN:
    case UI_PREVIEW:
    case UI_INTERNAL_PREVIEW:
    case UI_INTERNAL_RUN:
    case UI_INITIAL_PREVIEW:
      return true;
    default:
      return false;
    }
  }

  /**
   * Returns query type based on the endpoint information.
   *
   * @param clientInfos client info
   * @return query type
   */
  static QueryType getQueryType(final RpcEndpointInfos clientInfos) {
    if (clientInfos == null) {
      //TODO Come up with a better way to handle this
      return QueryType.ODBC;
    }

    final String name = clientInfos.getName().toLowerCase(Locale.ROOT);
    if (name.contains("jdbc") || name.contains("java")) {
      return QueryType.JDBC;
    }

    if (name.contains("odbc") || name.contains("c++")) {
      return QueryType.ODBC;
    }

    return QueryType.UNKNOWN;
  }

  public static WorkloadType getWorkloadType(final QueryType queryType) {
    switch(queryType) {
      case UI_PREVIEW:
        return WorkloadType.UI_PREVIEW;
      case UI_INTERNAL_PREVIEW:
      case UI_INITIAL_PREVIEW:
        return WorkloadType.INTERNAL_PREVIEW;
      case UI_RUN:
        return WorkloadType.UI_RUN;
      case UI_EXPORT:
        return WorkloadType.UI_DOWNLOAD;
      case UI_INTERNAL_RUN:
        return WorkloadType.INTERNAL_RUN;
      case JDBC:
        return WorkloadType.JDBC;
      case ODBC:
        return WorkloadType.ODBC;
      case REST:
        return WorkloadType.REST;
      case ACCELERATOR_DROP:
      case PREPARE_INTERNAL:
        return WorkloadType.DDL;
      case ACCELERATOR_CREATE:
      case ACCELERATOR_EXPLAIN:
        return WorkloadType.ACCELERATOR;
      case UNKNOWN:
      default:
        return WorkloadType.UNKNOWN;
    }
  }
}
